package com.plm.maque.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.hsf.HSFJSONUtils;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.plm.maque.common.pay.AlipayUtil;
import com.plm.maque.domain.bo.BizContent;
import com.plm.maque.service.PayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author Limi
 * @create 2020-06-28 21:12
 */
@Slf4j
@Service
public class PayServiceImpl implements PayService {

    private final AlipayUtil alipay;

    public PayServiceImpl(AlipayUtil alipay) {
        this.alipay = alipay;
    }

    @Override
    public String createOrder() throws AlipayApiException {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
        String format = dtf.format(LocalDate.now());

        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("麻雀充值：18278377807,100元话费充值.");
        model.setSubject("麻雀订单-" + format + alipay.outTradeNo());
        model.setOutTradeNo(format + alipay.outTradeNo());
        model.setTimeoutExpress("30m");
        model.setTotalAmount("99.70");
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(alipay.getNotifyUrl());

        AlipayTradeAppPayResponse response = alipay.getAlipayClient().sdkExecute(request);

        return response.getBody();
    }

    @Override
    public String createMqOrder(double allPrice) throws AlipayApiException {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
        String format = dtf.format(LocalDate.now());

        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("麻雀订单-" + format + alipay.outTradeNo() + allPrice + "元。");
        model.setSubject("麻雀订单-" + format + alipay.outTradeNo());
        model.setOutTradeNo(format + alipay.outTradeNo());
        model.setTimeoutExpress("30m");
        model.setTotalAmount(allPrice + "");
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(alipay.getNotifyUrl());

        AlipayTradeAppPayResponse response = alipay.getAlipayClient().sdkExecute(request);

        return response.getBody();
    }

    @Override
    public String handleCallback(HttpServletRequest request) {
        Map<String, String> params = new HashMap<>();
        //Trade trade = null;


        //1.从支付宝回调的request域中取值
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }

        //2.封装必须参数
        String out_trade_no = request.getParameter("out_trade_no"); // 商户订单号
        String orderType = request.getParameter("body"); // 订单内容
        String tradeStatus = request.getParameter("trade_status"); //交易状态

        //3.签名验证(对支付宝返回的数据验证，确定是支付宝返回的)
        boolean signVerified = false;
        try {
            //3.1调用SDK验证签名
            signVerified = AlipaySignature.rsaCheckV1(params, alipay.getAlipayPublicKey(), alipay.getCharset(), alipay.getSignType());
        } catch (AlipayApiException e) {
            log.error("验证签名异常：{}", e.getErrMsg());
        }
        //4.对验签进行处理
        if (signVerified) { //验签通过
            if (tradeStatus.equals("TRADE_SUCCESS")) { //只处理支付成功的订单: 修改交易表状态,支付成功
                //Trade trade = tradeService.selectByOrderNumber(out_trade_no);
                //trade.setTradeStatus((byte)3); //支付完成
                //int returnResult = tradeService.updateByPrimaryKeySelective(trade); //更新交易表中状态
                if (true) {
                    log.debug("**************验签通过, 业务操作完成！**************");
                    return "success";
                } else {
                    return "fail";
                }
            } else {
                return "fail";
            }
        } else {  //验签不通过
            log.error("**************验签失败**************");
            return "fail";
        }
    }

    @Override
    public String queryTrade(BizContent bizContent) throws AlipayApiException {
        //创建API对应的request类
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        String bizCnt = JSON.toJSONString(bizContent);
        //设置业务参数
        request.setBizContent(bizCnt);

        AlipayTradeRefundResponse response = alipay.getAlipayClient().execute(request);
        return response.getBody();
    }


}
